home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / WindowDepth.bproj / WindowDepth.m < prev    next >
Text File  |  1995-06-12  |  11KB  |  397 lines

  1. #import "WindowDepth.h"
  2. #import "MyNXBrowserCell.h"
  3. #import "common.h"
  4.  
  5. #define MAX_LINE_LEN 2048    // Maximum length of one preferences entry
  6.  
  7. /* Used to store temporary information */
  8. typedef struct {
  9.     NXAtom owner;        // The name of the application
  10.     int value;            // The WindowDepthLimit
  11.     BOOL test;            // YES if using Test prefix
  12. } appInfo;
  13.  
  14. /* Names used in defaults database (non-test mode) */
  15. static char *defaultnames[] = {
  16.     "TwoBitGray",
  17.     "EightBitGray",
  18.     "TwelveBitRGB",
  19.     "TwentyFourBitRGB"
  20. };
  21.  
  22. /* Names used in defaults database (test mode) */
  23. static char *defaulttestnames[] = {
  24.     "TestTwoBitGray",
  25.     "TestEightBitGray",
  26.     "TestTwelveBitRGB",
  27.     "TestTwentyFourBitRGB"
  28. };
  29.  
  30.  
  31. @interface WindowDepth(Private)
  32. - setBrowserCell:(appInfo *)set withMatrix:matrix atRow:(int)row;
  33. @end
  34.  
  35. @implementation WindowDepth(Private)
  36.  
  37. /*=========================================================================
  38.  * NAME        : setBrowserCell:withMatrix:
  39.  * DESCRIPTION : Insert a new cell in the browser.
  40.  *=========================================================================*/
  41. - setBrowserCell:(appInfo *)set withMatrix:matrix atRow:(int)row
  42. {
  43.     id cell;
  44.     
  45.     [matrix addRow];
  46.     cell = [matrix cellAt:row :0];    
  47.     [cell setStringValue:set->owner];
  48.     [cell setTag:row];
  49.     [cell setLoaded:YES];
  50.     [cell setLeaf:YES];
  51.     [cell setOwner:set->owner];
  52.     [cell setDepth:set->value];
  53.     [cell setTestMode:set->test];
  54.     return self;
  55. }
  56.  
  57. @end
  58.  
  59. @implementation WindowDepth
  60.  
  61. /*=========================================================================
  62.  * NAME        : + new
  63.  * DESCRIPTION : Called first time this section's button is clicked.
  64.  *=========================================================================*/
  65. + new
  66. {
  67.     self = [super new];
  68.     
  69.     if (![NXApp loadNibForLayout: "WindowDepth" owner: self])
  70.     return nil;
  71.     
  72.     // 'window' is an interface builder outlet.
  73.     view = [window contentView];    // 'view' MUST be initialized
  74.     [view removeFromSuperview];
  75.     [window setContentView: 0];        // Don't need the window for anything
  76.     [window free];            // So free it.
  77.     
  78.     // When multiple items (or none) are selected, no radio button is set
  79.     [appRadio setEmptySelectionEnabled:YES];
  80.     [appRadio clearSelectedCell];
  81.  
  82.     // Browser uses a custom Cell
  83.     [browser setCellClass:[MyNXBrowserCell class]];
  84.     
  85.     return self;
  86. }
  87.  
  88. /*=========================================================================
  89.  * NAME        : willSelect:
  90.  * DESCRIPTION : Before the view is added via addSubview.
  91.  *=========================================================================*/
  92. - willSelect: sender
  93. {
  94.     return self;
  95. }
  96.  
  97. /*=========================================================================
  98.  * NAME        : didSelect:
  99.  * DESCRIPTION : After the view is added via addSubview.
  100.  *=========================================================================*/
  101. - didSelect: sender
  102. {
  103.     // Enable relevant menu items
  104.     [NXApp enableEdit:COPY_ITEM];
  105.     [NXApp enableWindow:CLOSE_ITEM];
  106.     
  107.     // Rebuild the list of apps and preferences
  108.     [self rescanPrefs:self];
  109.     
  110.     return self;
  111. }
  112.  
  113.  
  114. /*=========================================================================
  115.  * NAME        : willUnselect:
  116.  * DESCRIPTION : Before removeFromSuperview
  117.  *=========================================================================*/
  118. - willUnselect: sender
  119. {
  120.     // Make sure that we aren't editing any text fields.
  121.     [[NXApp appWindow] endEditingFor:self];  
  122.     return self;
  123. }
  124.  
  125. /*=========================================================================
  126.  * NAME        : didUnselect:
  127.  * DESCRIPTION : Before removeFromSuperview
  128.  *=========================================================================*/
  129. - didUnselect: sender
  130. {
  131.     // Hide our info panel
  132.     [infoPanel orderOut:self];
  133.     
  134.     // Disable all Edit and Window menu items
  135.     [NXApp enableEdit: NO];
  136.     [NXApp enableWindow: NO];
  137.     return self;
  138. }
  139.  
  140. /*=========================================================================
  141.  * NAME        : didHide:
  142.  * DESCRIPTION : Application was just hidden.
  143.  *=========================================================================*/
  144. - didHide: sender
  145. {
  146.     return self;
  147. }
  148.  
  149. /*=========================================================================
  150.  * NAME        : didUnhide:
  151.  * DESCRIPTION : Application was just unhidden.
  152.  *=========================================================================*/
  153. - didUnhide: sender
  154. {
  155.     return self;
  156. }
  157.  
  158. /*=========================================================================
  159.  * NAME        : rescanPrefs:
  160.  * DESCRIPTION : Rescan the user's preferences.
  161.  *=========================================================================*/
  162. - rescanPrefs:sender
  163. {
  164.     // Cause the browser to reload
  165.     [browser loadColumnZero];
  166.     
  167.     return self;
  168. }
  169.  
  170. /*=========================================================================
  171.  * NAME        : itemSelected:
  172.  * DESCRIPTION : Target of NXBrowser.
  173.  *=========================================================================*/
  174. - itemSelected:sender
  175. {
  176.     id matrix;
  177.     List *aList;
  178.     id cell;
  179.     
  180.     // Get a list of all the selected cells in the browser
  181.     matrix = [browser matrixInColumn:0];
  182.     aList = [[List alloc] init];
  183.     [matrix getSelectedCells:aList];
  184.     
  185.     // Set the radio button and switch to match the selection
  186.     if ([aList count] == 0) {
  187.         [appRadio clearSelectedCell];
  188.     [appRadio display];
  189.     [appSwitch setState:0];
  190.         [appRadio setEnabled:NO];
  191.     [appSwitch setEnabled:NO];
  192.     } else if ([aList count] == 1) {
  193.         cell = [aList objectAt:0];
  194.         [appRadio selectCellWithTag:[cell depth]];
  195.     [appSwitch setState:[cell testMode]];
  196.     [appRadio setEnabled:YES];
  197.     [appSwitch setEnabled:YES];
  198.     } else {
  199.         if (![appRadio isEnabled]) {
  200.         [appRadio setEnabled:YES];
  201.         [appSwitch setEnabled:YES];
  202.     }
  203.         [appRadio clearSelectedCell];
  204.     [appRadio display];
  205.     [appSwitch setState:0];
  206.     }
  207.     [aList free];
  208.     return self;
  209. }
  210.  
  211. /*=========================================================================
  212.  * NAME        : browser:fillMatrix:inColumn:
  213.  * DESCRIPTION : Delegate message from browser requesting a reload.
  214.  *=========================================================================*/
  215. - (int)browser:sender fillMatrix:matrix inColumn:(int)column
  216. {
  217.     appInfo set;
  218.     FILE *fp;
  219.     char *line;
  220.     char *owner, *variable, *value;
  221.     NXAtom newOwner, prevOwner;
  222.     int i;
  223.     int globalSetting = USE_DEFAULT;
  224.     BOOL globalTestSetting = NO;
  225.     int count;
  226.     
  227.     // Call the 'dread' command as a subprocess
  228.     fp = popen("dread -l | sort -", "r");
  229.     if (!fp) {
  230.         NXLogError("WindowDepth.preferences: unable to popen(\"dread -l\")\n");
  231.         NXBeep();
  232.     return 0;
  233.     }
  234.     
  235.     // Get ready to read, erase previous information
  236.     line = malloc(MAX_LINE_LEN+1);
  237.     prevOwner = NULL;
  238.     set.owner = NULL;
  239.     count = 0;
  240.     
  241.     // Process the subprocess output, line by line
  242.     while (fgets(line, MAX_LINE_LEN, fp)) {
  243.         
  244.     // Isolate the first two fields
  245.     if (!(owner = strtok(line, " \"\n\t"))) {
  246.         continue;
  247.     }
  248.         if (!(variable = strtok(NULL, " \"\n\t"))) {
  249.         continue;
  250.     }
  251.     
  252.     // New owner found?
  253.     newOwner = NXUniqueString(owner);
  254.     if (newOwner != prevOwner) {
  255.         
  256.         // Add the previous owner to browser, unless it's GLOBAL
  257.         if (set.owner) {
  258.             if (strcmp(set.owner, "GLOBAL")) {
  259.             [self setBrowserCell:&set withMatrix:matrix atRow:count];
  260.             count++;
  261.         } else if (set.value != USE_DEFAULT) {
  262.             globalSetting = set.value;
  263.             globalTestSetting = set.test;
  264.         }
  265.         }
  266.         
  267.         // Set up this entry
  268.         set.owner = newOwner;
  269.         set.value = USE_DEFAULT;
  270.         set.test = NO;
  271.         prevOwner = newOwner;
  272.         }  
  273.   
  274.     // Is this the NXWindowDepthList entry?
  275.     if (strcmp(variable, "NXWindowDepthLimit")) {
  276.         continue;
  277.     }
  278.         
  279.     // Yes, find the setting
  280.     if (!(value = strtok(NULL, " \"\n\t"))) {
  281.         continue;
  282.     }
  283.  
  284.         // Is this a setting we know?
  285.     for (i = 0; i < 4; i++) {
  286.         if (!strcmp(value, defaultnames[i])) {
  287.             set.value = i;
  288.         set.test = NO;
  289.         }
  290.     }
  291.     
  292.     // Not found so try the Test modes
  293.     if (i == 4) {
  294.         for (i = 0; i < 4; i++) {
  295.             if (!strcmp(value, defaulttestnames[i])) {
  296.             set.value = i;
  297.             set.test = YES;
  298.         }
  299.         }
  300.     }
  301.     }
  302.  
  303.     // Write the last owner
  304.     if (set.owner) {
  305.         [self setBrowserCell:&set withMatrix:matrix atRow:count];
  306.         count++;
  307.     }
  308.         
  309.     // Deallocate resources
  310.     free(line);
  311.     pclose(fp);
  312.  
  313.     // Set the radio buttons for the GLOBAL setting
  314.     [defaultRadio selectCellWithTag:globalSetting];
  315.     [defaultSwitch setState:globalTestSetting];
  316.     
  317.     // Nothing is currently selected in the browser
  318.     [appRadio clearSelectedCell];
  319.     [appSwitch setState:0];
  320.     [appRadio setEnabled:NO];
  321.     [appSwitch setEnabled:NO];
  322.     
  323.     return count;    
  324. }
  325.  
  326. /*=========================================================================
  327.  * NAME        : setDefault:
  328.  * DESCRIPTION : Target of Default radio button matrix.
  329.  *=========================================================================*/
  330. - setDefault:sender
  331. {
  332.     char command[256];
  333.     int offset = [[defaultRadio selectedCell] tag];
  334.     
  335.     if (offset == 4) {
  336.         sprintf(command, "dremove -g NXWindowDepthLimit");
  337.     [defaultSwitch setState:0];
  338.     } else if ([defaultSwitch state]) {
  339.         sprintf(command, "dwrite -g NXWindowDepthLimit %s",
  340.             defaulttestnames[offset]);
  341.     } else {
  342.         sprintf(command, "dwrite -g NXWindowDepthLimit %s",
  343.             defaultnames[offset]);
  344.     }
  345.     system(command);
  346.     return self;
  347. }
  348.  
  349. /*=========================================================================
  350.  * NAME        : setApp:
  351.  * DESCRIPTION : Target of Application radio button matrix.
  352.  *=========================================================================*/
  353. - setApp:sender
  354. {
  355.     char command[256];
  356.     id matrix;
  357.     List *aList;
  358.     int count, total;
  359.     NXAtom owner;
  360.     id cell;
  361.     int offset = [[appRadio selectedCell] tag];
  362.     
  363.     // Get a list of all the selected cells in the browser
  364.     matrix = [browser matrixInColumn:0];
  365.     aList = [[List alloc] init];
  366.     [matrix getSelectedCells:aList];
  367.     
  368.     // Modify the defaults database to match
  369.     total = [aList count];
  370.     for (count = 0; count < total; count++) {
  371.         cell = [aList objectAt:count];
  372.     owner = [cell owner];
  373.         if (offset == 4) {
  374.         [appSwitch setState:0];
  375.             sprintf(command, "dremove %s NXWindowDepthLimit", owner);
  376.         } else if ([appSwitch state]) {
  377.             sprintf(command, "dwrite %s NXWindowDepthLimit %s",
  378.                 owner, defaulttestnames[offset]);
  379.         } else {
  380.             sprintf(command, "dwrite %s NXWindowDepthLimit %s",
  381.                 owner, defaultnames[offset]);
  382.         }
  383.         system(command);
  384.     
  385.     [cell setStringValue:owner];
  386.     [cell setLoaded:YES];
  387.     [cell setDepth:offset];
  388.     [cell setTestMode:[appSwitch state]];
  389.     }
  390.     
  391.     [aList free];
  392.     [browser displayColumn:0];
  393.     return self;
  394. }
  395.  
  396. @end
  397.